// Copyright (c) 2019 Presto Labs Pte. Ltd.
// Author: jaewon

#include <cstdlib>
#include <functional>
#include <iostream>

#include <boost/asio/dispatch.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <glog/logging.h>

#include "coin2/base/request/root_certificates.h"
#include "coin2/base/request/session_pool.h"

namespace ssl = boost::asio::ssl;  // from <boost/asio/ssl.hpp>
namespace request = coin2::base::request;

void Loop(boost::asio::io_context* io_ctx, boost::asio::yield_context yield) {
  boost::asio::steady_timer timer(*io_ctx);

  try {
    std::shared_ptr<request::SessionPool> pool(new request::SessionPool(io_ctx));
    boost::system::error_code ec;

    auto res = pool->CoroRequest("naver.com", 443, "/", yield[ec]);
    if (!ec) {
      LOG(INFO) << ec << "\n" << *res->raw_response;
      LOG(INFO) << "size: " << *res->raw_response->payload_size();
    } else {
      LOG(INFO) << ec;
    }

    res = pool->CoroRequest("naver.com", 443, "/", yield[ec]);
    if (!ec) {
      LOG(INFO) << ec << "\n" << *res->raw_response;
      LOG(INFO) << "size: " << *res->raw_response->payload_size();
    } else {
      LOG(INFO) << ec;
    }

    timer.expires_from_now(std::chrono::seconds(1));
    timer.async_wait(yield[ec]);

    res = pool->CoroRequest("naver.com", 443, "/", yield[ec]);
    if (!ec) {
      LOG(INFO) << ec << "\n" << *res->raw_response;
      LOG(INFO) << "size: " << *res->raw_response->payload_size();
    } else {
      LOG(INFO) << ec;
    }

    timer.expires_from_now(std::chrono::seconds(1));
    timer.async_wait(yield[ec]);

    res = pool->CoroRequest("google.com", 443, "/", yield[ec]);
    if (!ec) {
      LOG(INFO) << ec << "\n" << *res->raw_response;
    } else {
      LOG(INFO) << ec;
    }

    pool->AsyncShutdown();
  } catch (...) {
    LOG(ERROR) << boost::current_exception_diagnostic_information();
  }
}

/*
void Loop(boost::asio::io_context* io_ctx, boost::asio::yield_context yield) {
  const char host[] = "naver.co1m";
  const int port = 443;

  boost::asio::steady_timer timer(*io_ctx);

  ssl::context ssl_ctx{ssl::context::sslv23_client};

  try {
    std::shared_ptr<request::Session> session(
        new request::Session(io_ctx, &ssl_ctx, host, port));
    boost::system::error_code ec;
    auto res = session->CoroRequest("/", yield[ec]);

    if (!ec) {
      LOG(INFO) << ec << "\n" << *res->raw_response;
    } else {
      LOG(INFO) << ec;
    }

    timer.expires_from_now(std::chrono::seconds(1));
    timer.async_wait(yield[ec]);
    LOG(INFO) << "timer";

    res = session->CoroRequest("/", yield[ec]);
    if (!ec) {
      LOG(INFO) << ec << "\n" << *res->raw_response;
    } else {
      LOG(INFO) << ec;
    }

  } catch (...) {
    LOG(ERROR) << boost::current_exception_diagnostic_information();
  }
}
*/

int main(int argc, char* argv[]) {
  boost::asio::io_context io_ctx;
  boost::asio::spawn(io_ctx, std::bind(Loop, &io_ctx, std::placeholders::_1));
  io_ctx.run();

  return 0;
}
